package com.probiz.estore.common.model.cart;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

import com.probiz.estore.common.helper.ConfigUtil;
import com.probiz.estore.common.model.cart.base.ShoppingcartTbl;
import com.probiz.estore.common.model.customer.Customer;
import com.probiz.estore.common.model.product.ProductSku;
import com.probiz.estore.common.model.sales.Gift;
import com.probiz.estore.common.model.sales.PromoRule;
import com.probiz.estore.common.model.sales.PromoRuleElement;
import com.probiz.estore.common.model.sales.PromoRuleParameter;
import com.probiz.estore.common.model.system.AppUser;
import com.probiz.estore.common.service.CustomerService;
import com.probiz.estore.common.service.ProductService;
import com.probiz.estore.common.service.PromoService;
import com.probiz.estore.exception.OutOfStockException;
import com.probiz.estore.exception.UnderMinimumPurchaseQuantityException;
import com.probiz.estore.product.service.ProductSkuManager;
import com.probiz.estore.sales.service.GiftManager;
import com.probiz.estore.sales.service.PromoRuleManager;
import com.probiz.estore.webapp.util.RequestContext;

/**
 * Model - Business object  
 * Shoppingcart Object
 */
public class Shoppingcart extends ShoppingcartTbl implements Cloneable{

	private static final long	serialVersionUID	= 1L;
	
	public static final short ISUSECOUPON_YES = 1;
	public static final short ISUSECOUPON_NO = 0;

	private AppUser owner;
	
	//======start: RAM用于暂时保存促销规则模拟运行后的结果========/
	//保存购物车折扣金额RAM
	private BigDecimal cartDiscountAmountRAM = new BigDecimal(0);
	//保存运输信息折扣RAM
	private String shippingDiscountInfoRAM = "";
	//保存获得积分RAM
	private Integer gainedPointRAM = Integer.valueOf(0);
	//保存获得优惠券类型RAM
	private Integer gainedCouponTypeIdRAM = null;
	//是否已经对金额进行优惠
	private boolean hasDiscountOfMoney = false;
	//是否已经对积分进行优惠
	private boolean hasDiscountOfPoint = false;
	//能进行购物车运算的shoppingcartItems
	private Set<ShoppingcartItem> shoppingCartItemsForCalculation = new HashSet<ShoppingcartItem>();
	//能进行促销运算的shoppingcartItems
	private Set<ShoppingcartItem> shoppingCartItemsForPromo = new HashSet<ShoppingcartItem>();
	//能进行促销运算条件的shoppingcartItems
	private Set<ShoppingcartItem> shoppingCartItemsForPromoInCondition = new HashSet<ShoppingcartItem>();
	//能进行促销运算动作的shoppingcartItems
	private Set<ShoppingcartItem> shoppingCartItemsForPromoInAction = new HashSet<ShoppingcartItem>();
	//保存shoppingcart Promotion RAM
	private Set<ShoppingcartPromotion> shoppingCartPromotionsRAM = new HashSet<ShoppingcartPromotion>();
	//======end: RAM用于暂时保存促销规则模拟运行后的结果========/
	
	//======start: 礼品========/
	//保存获得赠送礼品的ID
	private String gainedGiftIds = "";
	//======end: 礼品========/
	
	public Shoppingcart () {
		super();
	}

	/**
	 * Default Key Fields Constructor for class Shoppingcart
	 */
	public Shoppingcart (
		 Integer in_shoppingCartId
		) {
		super (
		  in_shoppingCartId
		);
	}
	public Object clone(){
		Shoppingcart cart=null;
		try{
			cart=(Shoppingcart)super.clone();			
		}catch(CloneNotSupportedException  e){
			e.printStackTrace();	
		}
		return cart;
	}
	
	public java.math.BigDecimal getCartDiscountAmountRAM() {
		return cartDiscountAmountRAM;
	}

	public void setCartDiscountAmountRAM(java.math.BigDecimal cartDiscountAmountRAM) {
		this.cartDiscountAmountRAM = cartDiscountAmountRAM;
	}

	public String getShippingDiscountInfoRAM() {
		return shippingDiscountInfoRAM;
	}

	public void setShippingDiscountInfoRAM(String shippingDiscountInfoRAM) {
		this.shippingDiscountInfoRAM = shippingDiscountInfoRAM;
	}

	public Integer getGainedPointRAM() {
		return gainedPointRAM;
	}

	public void setGainedPointRAM(Integer gainedPointRAM) {
		this.gainedPointRAM = gainedPointRAM;
	}

	public Integer getGainedCouponTypeIdRAM() {
		return gainedCouponTypeIdRAM;
	}

	public void setGainedCouponTypeIdRAM(Integer gainedCouponTypeIdRAM) {
		this.gainedCouponTypeIdRAM = gainedCouponTypeIdRAM;
	}

	public boolean isHasDiscountOfMoney() {
		return hasDiscountOfMoney;
	}

	public void setHasDiscountOfMoney(boolean hasDiscountOfMoney) {
		this.hasDiscountOfMoney = hasDiscountOfMoney;
	}

	public boolean isHasDiscountOfPoint() {
		return hasDiscountOfPoint;
	}

	public void setHasDiscountOfPoint(boolean hasDiscountOfPoint) {
		this.hasDiscountOfPoint = hasDiscountOfPoint;
	}

	public Set<ShoppingcartItem> getShoppingCartItemsForCalculation() {
		return shoppingCartItemsForCalculation;
	}

	public void setShoppingCartItemsForCalculation(
			Set<ShoppingcartItem> shoppingCartItemsForCalculation) {
		this.shoppingCartItemsForCalculation = shoppingCartItemsForCalculation;
	}
	
	public void addShoppingCartItemForCalculation(
			ShoppingcartItem shoppingCartItemForCalculation) {
		this.shoppingCartItemsForCalculation.add(shoppingCartItemForCalculation);
	}
	
	public void clearShoppingCartItemsForCalculation(){
		this.shoppingCartItemsForCalculation.clear();
	}
	
	public Set<ShoppingcartItem> getShoppingCartItemsForPromo() {
		return shoppingCartItemsForPromo;
	}

	public void setShoppingCartItemsForPromo(
			Set<ShoppingcartItem> shoppingCartItemsForPromo) {
		this.shoppingCartItemsForPromo = shoppingCartItemsForPromo;
	}
	
	public void addShoppingCartItemForPromo(
			ShoppingcartItem shoppingCartItemForPromo) {
		this.shoppingCartItemsForPromo.add(shoppingCartItemForPromo);
	}
	
	public void clearShoppingCartItemsForPromo(){
		this.shoppingCartItemsForPromo.clear();
	}
	
	public Set<ShoppingcartItem> getShoppingCartItemsForPromoInCondition() {
		return shoppingCartItemsForPromoInCondition;
	}

	public void setShoppingCartItemsForPromoInCondition(
			Set<ShoppingcartItem> shoppingCartItemsForPromo) {
		this.shoppingCartItemsForPromoInCondition = shoppingCartItemsForPromo;
	}
	
	public void addShoppingCartItemForPromoInCondition(ShoppingcartItem shoppingCartItemForPromoInCondition){
		this.shoppingCartItemsForPromoInCondition.add(shoppingCartItemForPromoInCondition);
	}
	
	public void clearShoppingCartItemsForPromoInCondition(){
		this.shoppingCartItemsForPromoInCondition.clear();
	}

	public Set<ShoppingcartItem> getShoppingCartItemsForPromoInAction() {
		return shoppingCartItemsForPromoInAction;
	}

	public void setShoppingCartItemsForPromoInAction(
			Set<ShoppingcartItem> shoppingCartItemsForPromoInAction) {
		this.shoppingCartItemsForPromoInAction = shoppingCartItemsForPromoInAction;
	}
	
	public void addShoppingCartItemForPromoInAction(
			ShoppingcartItem shoppingCartItemForPromoInAction) {
		this.shoppingCartItemsForPromoInAction.add(shoppingCartItemForPromoInAction);
	}
	
	public void clearShoppingCartItemsForPromoInAction(){
		this.shoppingCartItemsForPromoInAction.clear();
	}
	
	public Set<ShoppingcartPromotion> getShoppingCartPromotionsRAM() {
		return shoppingCartPromotionsRAM;
	}

	public void setShoppingCartPromotionsRAM(
			Set<ShoppingcartPromotion> shoppingCartPromotionsRAM) {
		this.shoppingCartPromotionsRAM = shoppingCartPromotionsRAM;
	}
	
	public void addShoppingCartPromotionRAM(
			ShoppingcartPromotion shoppingcartPromotion) {
		this.shoppingCartPromotionsRAM.add(shoppingcartPromotion);
	}
	
	/**
	 * 获赠的礼品
	 * @return
	 */
	public String getGainedGiftIds() {
		return gainedGiftIds;
	}

	/**
	 * 获赠的礼品
	 * @return
	 */
	public void setGainedGiftIds(String gainedGiftIds) {
		this.gainedGiftIds = gainedGiftIds;
	}
	
	public void clearShoppingCartPromotionsRAM(){
		this.shoppingCartPromotionsRAM.clear();
	}

	//批量更新商品项的购物数量
	public boolean updateProductItems(String[] skuCodes, Integer[] quantitys) throws OutOfStockException, UnderMinimumPurchaseQuantityException {
		if (skuCodes != null) {
			for (int i = 0; i< skuCodes.length; i ++) {
				String skuCode = skuCodes[i];
				Integer quantity = quantitys[i];
				getProductService().checkInventory(skuCode, quantity);
				getProductService().checkMinPurchaseQuantity(skuCode, quantity);
				
				ShoppingcartItem shoppingcartItem = this.getShoppingcartItemBySkuCode(skuCode);
				if (shoppingcartItem == null) {
					ProductSku sku = getProductManager().getProductSkuPojoByProductSkuCode(skuCode);
					if (sku == null) continue;
					shoppingcartItem = new ShoppingcartItem(sku, quantity);
					addShoppingCartItem(shoppingcartItem);
				} else {
					shoppingcartItem.setQuantity(quantity);
					shoppingcartItem.calculateSalesAndWholesalePrice();
				}
			}
		}
		refresh();
		
		return true;
	}
	
	public boolean addProductItem(String skuCode, Integer quantity) {
		ShoppingcartItem shoppingcartItem = this.getShoppingcartItemBySkuCode(skuCode);
		if (shoppingcartItem == null) {
			ProductSku sku = getProductManager().getProductSkuPojoByProductSkuCode(skuCode);
			if (sku == null) return false;
			sku.getProduct().getProductName();	//force to load the related product entity
			sku.getOrderSkuDisplayOption();		//force to load the sku options
			shoppingcartItem = new ShoppingcartItem(sku, quantity);
			addShoppingCartItem(shoppingcartItem);
		} else {
			shoppingcartItem.plusQuantity(quantity);
		}
		refresh();
		
		return true;
	}
	
	public boolean addProductItem(String parentSkuCode, String[] childSkus, Integer quantity) {
		this.addProductItem(parentSkuCode, quantity);
//		ShoppingcartItem parentShoppingcartItem = this.getShoppingcartItemBySkuCode(parentSkuCode);
		if (childSkus != null) {
			for (String childSku: childSkus) {
				this.addProductItem(childSku, quantity);
//				ShoppingcartItem childShoppingcartItem = this.getShoppingcartItemBySkuCode(childSku);
//				childShoppingcartItem.setParent(parentShoppingcartItem);
			}
		}
		refresh();
		
		return true;
	}
	
	public boolean addGiftCertificateItem(ShoppingcartItemGc shoppingcartItemGc) {
		int num = this.getGiftCertificateItems().size() + 1;
		shoppingcartItemGc.setShoppingcartItemGcId(num);	//因为不保存数据库了，手动为它设个id方便ajax操作
		ShoppingcartItem shoppingcartItem = new ShoppingcartItem(shoppingcartItemGc);
		addShoppingCartItem(shoppingcartItem);
		subtotal = subtotal.add(shoppingcartItem.getTotal());
		refresh();
		
		return true;
	}
	
	public boolean addGiftItem(String skuCode, Integer quantity) {
		ShoppingcartItem shoppingcartItem = this.getShoppingcartItemByGiftSkuCode(skuCode);
		if (shoppingcartItem == null) {
			Gift sku = getGiftManager().getGiftByGiftCode(skuCode);
			if (sku == null) return false;
			sku.getGiftName();	//force to load the related product entity
			shoppingcartItem = new ShoppingcartItem(sku, quantity);
			addShoppingCartItem(shoppingcartItem);
		} else {
			shoppingcartItem.plusQuantity(quantity);
		}
		refresh();
		
		return true;
	}
	
	public boolean updateProductItem(String skuCode, Integer quantity) {
		ShoppingcartItem item = this.getShoppingcartItemBySkuCode(skuCode);
		if (item == null) {
			return false;
		} else {
			Integer delta = quantity - item.getQuantity();
			item.plusQuantity(delta);
		}
		refresh();
		
		return true;
	}
	
	public boolean removeProductItem(String skuCode) {
		ShoppingcartItem shoppingcartItem = getShoppingcartItemBySkuCode(skuCode);
		super.removeShoppingcartItem(shoppingcartItem);
		refresh();
		return true;
	}
	
	public boolean removeGiftCertificateItem(String shoppingcartItemGcId) {
		for (ShoppingcartItem shoppingcartItem : getGiftCertificateItems()) {
			ShoppingcartItemGc shoppingcartItemGc = shoppingcartItem.getShoppingcartItemGc();
			String num = shoppingcartItemGc.getShoppingcartItemGcId().toString();
			if (num.equals(shoppingcartItemGcId)) {
				super.removeShoppingcartItem(shoppingcartItem);
				refresh();
				return true;
			}
		}
		refresh();
		return false;
	}
	
	//清空购物车
	public boolean clear() {
		this.getShoppingCartItems().clear();
		refresh();
		return true;
	}
	
	@Override
	//使用优惠卷
	public void setUsedCouponNo(String usedCouponNo) {
		if (usedCouponNo == null) {
			setIsUsedCoupon(ISUSECOUPON_NO);
		} else {
			setIsUsedCoupon(ISUSECOUPON_YES);
		}
		super.setUsedCouponNo(usedCouponNo);
		refresh();		//重新计算优惠
		
		//再一次检查优惠卷是否能够应用到当前的购物中
		if (isCouponApplied()) {
			setIsUsedCoupon(ISUSECOUPON_YES);
		} else {
			setIsUsedCoupon(ISUSECOUPON_NO);
			super.setUsedCouponNo(null);
		}
	}
	
	//购物车是否使用了优惠券
	public boolean isCouponApplied() {
		for (ShoppingcartPromotion promo : getShoppingCartPromotions()) {
			if (PromoRule.PROMOTION_TYPE_COUPONPROMOTION.equals(promo.getType().trim())) {
				//来到这里说明优惠卷生效了
				return true;	
			}
		}
		
		return false;
	}
	
	/**
	 * 根据sku code从购物车中取出相应的item
	 */
	public ShoppingcartItem getShoppingcartItemBySkuCode(String skuCode) {
		for (ShoppingcartItem shoppingcartItem : getProductItems()) {
			ProductSku product = shoppingcartItem.getProductSku();
			
			if (product.getProductSkuCode().equals(skuCode)) {
				return shoppingcartItem;
			}
		}
		return null;
	}
	
	public BigDecimal getWeight() {
		BigDecimal result = new BigDecimal(0);
		for (ShoppingcartItem shippingcartItem: super.getShoppingCartItems()) {
			if (shippingcartItem.isProduct()) {
				result = result.add(shippingcartItem.getWeight());
			}
		}
		
		return result;
	}
	
	//取得购物车里所有的实体商品项
	public List<ShoppingcartItem> getPhysicalProductItems() {
		List<ShoppingcartItem> result = new ArrayList<ShoppingcartItem>();
		for (ShoppingcartItem shippingcartItem: super.getShoppingCartItems()) {
			if (shippingcartItem.isPhysicalProduct()) {
				result.add(shippingcartItem);
			}
		}
		
		return result;
	}
	
	//取得购物车里所有的数字（虚拟）商品项
	public List<ShoppingcartItem> getDigitalProductItems() {
		List<ShoppingcartItem> result = new ArrayList<ShoppingcartItem>();
		for (ShoppingcartItem shoppingcartItem: super.getShoppingCartItems()) {
			if (shoppingcartItem.isDigitalProduct()) {
				result.add(shoppingcartItem);
			}
		}
		
		return result;
	}
	
	//取得购物车里所有普通商品（非礼品券和积分换礼品）
	public List<ShoppingcartItem> getProductItems() {
		List<ShoppingcartItem> result = new ArrayList<ShoppingcartItem>();
		for (ShoppingcartItem shoppingcartItem: super.getShoppingCartItems()) {
			if (shoppingcartItem.isProduct()) {
				result.add(shoppingcartItem);
			}
		}
		return result;
	}
	
	/**
	 * 根据sku code从购物车中取出相应的item
	 */
	public ShoppingcartItem getShoppingcartItemByGiftSkuCode(String skuCode) {
		for (ShoppingcartItem shoppingcartItem : getGiftItems()) {
			Gift gift = shoppingcartItem.getGift();
			
			if (gift.getGiftCode().equals(skuCode)) {
				return shoppingcartItem;
			}
		}
		return null;
	}
	
	//取得购物车里所有礼品（非礼品券和商品）
	public List<ShoppingcartItem> getGiftItems() {
		List<ShoppingcartItem> result = new ArrayList<ShoppingcartItem>();
		for (ShoppingcartItem shoppingcartItem: super.getShoppingCartItems()) {
			if (shoppingcartItem.is_Gift()) {
				result.add(shoppingcartItem);
			}
		}
		return result;
	}
	
	//取得购物车里所有的礼品券项
	public List<ShoppingcartItem> getGiftCertificateItems() {
		List<ShoppingcartItem> result = new ArrayList<ShoppingcartItem>();
		for (ShoppingcartItem shoppingcartItem: super.getShoppingCartItems()) {
			if (shoppingcartItem.isGiftCertificate()) {
				result.add(shoppingcartItem);
			}
		}
		
		return result;
	}
	
	public void setOwner(AppUser owner) {
		if (owner != null) {
			this.owner = owner;
			super.customerId = owner.getAppuserId();
		}
	}
	public Customer getOwner() {
		if (getCustomerId() != null) {
			return getCustomerService().getByAppUserId(getCustomerId());
		}
		return null;
	}
	
	//刷新购物车，重新计算优惠信息
	public void refresh() {
		PromoService promoService = getPromoService();
		if (promoService != null) {
			promoService.appendPromoInfo(this, owner);
		}
	}
	
	private ProductSkuManager getProductManager() {
		return (ProductSkuManager)RequestContext.getSpringBeanById("productSkuManager");
	}
	
	private ProductService getProductService() {
		return (ProductService)RequestContext.getSpringBeanById("productService");
	}
	
	private PromoService getPromoService() {
		return (PromoService)RequestContext.getSpringBeanById("promoService");
	}
	
	private CustomerService getCustomerService() {
		return (CustomerService)RequestContext.getSpringBeanById("customerService");
	}
	
	private GiftManager getGiftManager() {
		return (GiftManager)RequestContext.getSpringBeanById("giftManager");
	}
	
	private PromoRuleManager getPromoRuleManager() {
		return (PromoRuleManager)RequestContext.getSpringBeanById("promoRuleManager");
	}
	
	public BigDecimal getTax() {
		BigDecimal result = new BigDecimal(0);
		List<ShoppingcartItem> items = getProductItems();
		for (ShoppingcartItem shoppingcartItem : items) {
			result = result.add(shoppingcartItem.getTax());
		}
		
		return result;
	}
	
	public void resetTax() {
		List<ShoppingcartItem> items = getProductItems();
		for (ShoppingcartItem shoppingcartItem : items) {
			shoppingcartItem.setTax(new BigDecimal(0));
			shoppingcartItem.setTaxName("");
		}
	}
	
	//取得购物车里商品的ID，多个ID用逗号隔开
	public String getProductIds() {
		String result = "";
		List<ShoppingcartItem> items = getProductItems();
		StringBuffer buf = new StringBuffer();
		for (ShoppingcartItem item : items) {
			buf.append(item.getProductSku().getProductId()).append(",");
		}
		result = buf.toString();
		if (StringUtils.isNotEmpty(result)) {
			result = result.substring(0, result.length() - 1);
		}
		
		return result;
	}
	
	public void checkInventory() throws OutOfStockException {
		for(ShoppingcartItem item: getProductItems()){
			getProductService().checkInventory(item.getProductSku().getProductSkuCode(), item.getQuantity());
		}
	}
	
	//购物车总金额是否低于每笔订单允许的最低金额
	public boolean isBelowMinimumPurchaseAmount() {
		int minAmount = ConfigUtil.getInstance().getMinimumPurchaseAmount();
		if (total != null && total.compareTo(new BigDecimal(minAmount)) < 0) {
			return true;
		} else {
			return false;
		}
	}


	@Override
	public int hashCode() {
		return super.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		return super.equals(obj);
	}
	
	//获得赠送礼品列表
	public List<Gift> getPromoGiftList(){
		List<Gift> result = new ArrayList<Gift>();
		List<PromoRule> promoRules = new ArrayList<PromoRule>();
		Map<Integer,Gift> map = new HashMap<Integer,Gift>();
		for (ShoppingcartPromotion shoppingcartPromotion : getShoppingCartPromotions()) {
			PromoRule promoRule = getPromoRuleManager().getById(shoppingcartPromotion.getPromoRuleId());
			promoRules.add(promoRule);
		}
		// 获取促销规则中有库存的礼品列表
		List<PromoRule> promoRuleList = getPromoService().getShoppingcartPromotion(promoRules);
		for (PromoRule promoRule : promoRuleList) {
			for(PromoRuleElement promoRuleElement : promoRule.getPromoRuleElements()){
				String giftId=""; Integer quantity =0;
				for(PromoRuleParameter promoRuleParameter: promoRuleElement.getPromoRuleParameters()){
					if (promoRuleParameter.getParamName().equals("GIFT")) {
						giftId = promoRuleParameter.getParamValue();
					}else if (promoRuleParameter.getParamName().equals("DISCOUNT_QUANTITY")){
						quantity = new Integer(promoRuleParameter.getParamValue());
					}
				}
				// 当礼品库存足够时，获取礼品数量
				if(giftId.length() > 0 && quantity > 0) {
					Gift gift = this.getGiftManager().getById(new Integer(giftId).intValue());
					//礼品相同时累计数量，否则记录当前赠送数量。结果存放在map中
					 if(map.containsKey(Integer.parseInt(giftId))){
						 Integer val = gift.getOrderSkuQuantity() + quantity;
						 gift.setOrderSkuQuantity(val);
						 map.put(gift.getId(), gift);
					 }else {
						 gift.setOrderSkuQuantity(quantity);
						 map.put(gift.getId(), gift);
					}
				}
			}
		}
		for (Gift gift : map.values()) {
			result.add(gift);
		}
		return result;
	}
}
